import pandas as pd
import numpy as np
import plotly.graph_objects as go
import plotly.express as px
import matplotlib.pyplot as plt
from scipy import stats


df = pd.read_csv('winequality_red.csv',encoding='utf-8')

#创建新特征total acid
df['total acid'] = df['fixed acidity'] + df['volatile acidity'] + df['citric acid']

#红酒品质和理化特征的关系分析
def characters_by_quality_boxplot(df):
    #获取列名
    lst = df.columns.tolist()
    lst.remove('quality')
    #设置全图行列
    n_row = 4
    n_col = 3
    #创建画布和子图
    fig, axes = plt.subplots(n_row,n_col,figsize=(10,9))
    for i, col in enumerate(lst):
        #设置子图行列关系
        row = i // n_col
        col_i =i % n_col
        #第row行第col_i个子图
        ax = axes[row,col_i]
        #绘制箱线图
        df.boxplot(column=col,by = 'quality',figsize=(10,9),ax = ax)
        ax.set_title(col)
    plt.suptitle('')
    plt.tight_layout()
    plt.show()
#质量评估
def quality_evaluation(df):
    #计算相关性矩阵
    correlation_matrix = df.corr()
    #创建掩码，用于去除相关性热图中冗余部分
    mask = np.triu(np.ones_like(correlation_matrix, dtype=bool))
    #创建相关性热图
    fig = go.Figure(data=go.Heatmap(
        z=correlation_matrix.mask(mask),
        x=correlation_matrix.columns,
        y=correlation_matrix.columns,
        #黄绿蓝配色
        colorscale='YlGnBu',
        #无数据区域不显示悬停信息
        hoverongaps=False,
        #定义悬停文本
        hovertemplate='x=%{x}<br>y=%{y}<br>Correlation=%{z:.4f}<extra></extra>',
        #显示两位小数
        texttemplate="%{z:.2f}",  # 显示两位小数
    ))
    #更新布局
    fig.update_layout(
        title="理化特征与品质的相关性热图",
        height=800,
        width=800
    )
    #显示图形
    fig.show()
#相关性分析
def correlation_analysis(df, x, y):
    plt.rcParams['font.family'] = ['SimHei']

    #设置图片清晰度
    plt.rcParams['figure.dpi'] = 300
    #创建画布和子图
    plt.figure(figsize=(10, 6))
    #绘制散点图
    plt.scatter(df[x], df[y], alpha=0.6)
    #设置标题和轴标签
    plt.title(f'Correlation of {x} and {y}')
    plt.xlabel(x)
    plt.ylabel(y)
    #计算回归直线参数
    slope, intercept, r_value, p_value, std_err = stats.linregress(df[x], df[y])
    r_squared = r_value ** 2
    #生成回归直线的y值
    y_pred = slope * df[x] + intercept
    #添加回归直线
    plt.plot(df[x], y_pred, color='red', linestyle='--', label='回归直线')
    #添加回归方程和R²标注
    equation_text = f'回归方程: y = {slope:.2f}x + {intercept:.2f}\nR^2 = {r_squared:.4f}'
    plt.annotate(equation_text,
                 xy=(0.05, 0.95),
                 xycoords='axes fraction',
                 bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="gray", lw=1),
                 ha='left',
                 va='top')

    # 添加图例
    plt.legend()
    # 显示网格线
    plt.grid(True, linestyle='--', alpha=0.7)
    # 自动调整布局
    plt.tight_layout()
    # 显示图形
    plt.show()

#多变量分析
def multi_variables_analysis(df,x,y,z='quality'):
    if z == 'quality':
        df = df.sort_values(by=z)
        df[z] = df[z].astype(str)

    fig = px.scatter(
        x = df[x],
        y = df[y],
        color = df[z],
        color_continuous_scale='RdBu',
        labels={'color':z},

    )
    fig.update_layout(xaxis_title=x,yaxis_title=y)
    fig.show()

characters_by_quality_boxplot(df)

quality_evaluation(df)

correlation_analysis(df,'density','alcohol')
correlation_analysis(df,'pH','fixed acidity')
correlation_analysis(df,'pH','volatile acidity')
correlation_analysis(df,'pH','total sulfur dioxide')
correlation_analysis(df,'pH','sulphates')
correlation_analysis(df,'pH','total acid')

multi_variables_analysis(df,'alcohol','volatile acidity')
multi_variables_analysis(df,'fixed acidity','citric acid','pH')







